unit basicio_map;

{$mode objfpc}{$H+}


{
  Stores the playfield of an IO-object
}

interface

uses
  Classes, SysUtils, basicio_field, basicio_harbor, basicio_city, basicio_street;

type
  { TMap }

  TMap = class
    private
      FThiefPosition: TPoint;
      FFieldList: TFieldList;
      FHarborList: THarborList;
      FCityList: TCityList;
      FStreetList: TStreetList;
      function GetCity(AID: integer): TCity;
      function GetCity(APos: TCityPosition): TCity;
      function GetCityCount: integer;
      function GetFieldCount: integer;
      function GetFields(AX, AY: integer): TField;
      function GetFields(APos: TPoint): TField;
      function GetFields(AID: integer): TField;
      function GetHarbor(AID: integer): THarbor;
      function GetHarborCount: integer;
      function GetStreet(AID: integer): TStreet;
      function GetStreet(APos: TStreetPosition): TStreet;
      function GetStreetCount: integer;
      function GetThiefPosition: TFieldPosition;
    public
      property ThiefPositionAsPoint: TPoint read FThiefPosition;
      property ThiefPositionAsFieldPosition: TFieldPosition read GetThiefPosition;
      property FieldsByInt[AX,AY: integer]: TField read GetFields;
      property FieldsByPos[APos: TPoint]: TField read GetFields;
      property FieldsByID[AID: integer]: TField read GetFields;
      property FieldCount: integer read GetFieldCount;
      property CityCount: integer read GetCityCount;
      property CityByID[AID: integer]: TCity read GetCity;
      property CityByPos[AID: TCityPosition]: TCity read GetCity;
      property HarborCount: integer read GetHarborCount;
      property Harbor[AID: integer]: THarbor read GetHarbor;
      property StreetCount: integer read GetStreetCount;
      property StreetByID[AID: integer]: TStreet read GetStreet;
      property StreetByPos[APos: TStreetPosition]: TStreet read GetStreet;
    public
      constructor Create;
      destructor Destroy; override;
    public
      procedure AddStreet(AStreet: TStreet);
      procedure AddCity(ACity: TCity);
      procedure SetThiefPosition(AX,AY: integer);
      procedure ResetStreets;
      procedure ResetCities;
  end;

implementation

{ TMap }

function TMap.GetFields(AX, AY: integer): TField;
var
  i:integer;
begin
  for i:=0 to FFieldList.count-1 do
  begin
    if (FFieldList.Items[i].X = AX) and (FFieldList.Items[i].Y = AY) then
    begin
      result := FFieldList.Items[i];
      exit;
    end;
  end;
end;

function TMap.GetCityCount: integer;
begin
  result := FCityList.count;
end;

function TMap.GetFieldCount: integer;
begin
  result := FFieldList.Count;
end;

function TMap.GetCity(AID: integer): TCity;
begin
  result := FCityList.Items[AID];
end;

function TMap.GetCity(APos: TCityPosition): TCity;
var
  i: integer;
begin
  result := nil;
  for i:=0 to FCityList.count-1 do
  begin
    if (FCityList.Items[i].Position = APos) then
    begin
      result := FCityList.Items[i];
      exit;
    end;
  end;
end;

function TMap.GetFields(APos: TPoint): TField;
var
  i:integer;
begin
  result := nil;
  for i:=0 to FFieldList.count-1 do
  begin
    if (FFieldList.Items[i].X = APos.X) and (FFieldList.Items[i].Y = APos.Y) then
    begin
      result := FFieldList.Items[i];
      exit;
    end;
  end;
end;

function TMap.GetFields(AID: integer): TField;
begin
  result := FFieldList.Items[AID];
end;

function TMap.GetHarborCount: integer;
begin
  result := FHarborList.Count;
end;

function TMap.GetHarbor(AID: integer): THarbor;
begin
  result := FHarborList.Items[AID];
end;

function TMap.GetStreet(AID: integer): TStreet;
begin
  result := FStreetList.Items[AID];
end;

function TMap.GetStreet(APos: TStreetPosition): TStreet;
var
  i: integer;
begin
  result := nil;
  for i:=0 to FStreetList.count-1 do
  begin
    if (FStreetList.Items[i].Position = APos) then
    begin
      result := FStreetList.Items[i];
      exit;
    end;
  end;
end;

function TMap.GetStreetCount: integer;
begin
  result := FStreetList.count;
end;

function TMap.GetThiefPosition: TFieldPosition;
begin
  result.x := self.ThiefPositionAsPoint.x;
  result.y := self.ThiefPositionAsPoint.y;
end;

constructor TMap.Create;
var
  i: integer;
begin
  inherited;

  //Fields
  FFieldList := TFieldList.Create;

  FFieldList.Add(TField.Create(1,1));

  FFieldList.Add(TField.Create(2,1));
  FFieldList.Add(TField.Create(2,2));

  FFieldList.Add(TField.Create(3,1));
  FFieldList.Add(TField.Create(3,2));
  FFieldList.Add(TField.Create(3,3));

  FFieldList.Add(TField.Create(4,1));
  FFieldList.Add(TField.Create(4,2));

  FFieldList.Add(TField.Create(5,1));
  FFieldList.Add(TField.Create(5,2));
  FFieldList.Add(TField.Create(5,3));

  FFieldList.Add(TField.Create(6,1));
  FFieldList.Add(TField.Create(6,2));

  FFieldList.Add(TField.Create(7,1));
  FFieldList.Add(TField.Create(7,2));
  FFieldList.Add(TField.Create(7,3));

  FFieldList.Add(TField.Create(8,1));
  FFieldList.Add(TField.Create(8,2));

  FFieldList.Add(TField.Create(9,1));

  //Harbors
  FHarborList := THarborList.Create;
  for i:=1 to 9 do
  begin
    FHarborList.Add(THarbor.create(i));
  end;

  //Cities
  FCityList := TCityList.create;
  //streets
  FStreetList := TStreetList.create;
end;

destructor TMap.Destroy;
begin
  FStreetList.Free;
  FCityList.Free;
  FHarborList.Free;
  FFieldList.Free;
  inherited Destroy;
end;

procedure TMap.AddStreet(AStreet: TStreet);
var
  i: integer;
begin
  for i := 0 to FStreetList.Count-1 do
  begin
    if FStreetList.Items[i].Position = AStreet.Position then
    begin
      AStreet.Free;
      exit;
    end;
  end;
  FStreetList.Add(AStreet);
end;

procedure TMap.AddCity(ACity: TCity);
var
  i: integer;
begin
  for i := 0 to FCityList.Count-1 do
  begin
    if FCityList.Items[i].Position = ACity.Position then
    begin
      FCityList.Items[i].isExtended := ACity.isExtended;
      ACity.Free;
      exit;
    end;
  end;
  FCityList.Add(ACity);
end;

procedure TMap.SetThiefPosition(AX, AY: integer);
begin
  FThiefPosition.X := AX;
  FThiefPosition.Y := AY;
end;

procedure TMap.ResetStreets;
begin
  FStreetList.Clear;
end;

procedure TMap.ResetCities;
begin
  FCityList.Clear;
end;

end.

